package cn.bdqn.filter;

import cn.bdqn.dao.UserDao;
import cn.bdqn.entity.AuthorityRole;
import cn.bdqn.entity.AuthorityUser;
import cn.bdqn.util.JwtUtil;
import cn.bdqn.util.RsaKeyProperties;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ProjectName: springSecuritySeparate
 * @Package: cn.bdqn.filter
 * @Author: huat
 * @Date: 2019/12/24 17:04
 * @Version: 1.0
 */

public class JwtTokenFilter extends UsernamePasswordAuthenticationFilter {

    private AuthenticationManager authentication;
    private RsaKeyProperties rsaKeyProperties;
    private UserDao userDao;


    public JwtTokenFilter(AuthenticationManager authentication, RsaKeyProperties rsaKeyProperties,UserDao userDao) {
        this.authentication = authentication;
        this.rsaKeyProperties = rsaKeyProperties;
        this.userDao=userDao;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {

        try {
            //从ajax请求流读取参数，转换成AuthorityUser实体类
            AuthorityUser authorityUser= new ObjectMapper().readValue(request.getInputStream(), AuthorityUser.class);
            //参数是前台传过来的
            UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(authorityUser.getUsername(), authorityUser.getPassword());

            return authentication.authenticate(authRequest);

        } catch (IOException e) {
            e.printStackTrace();
          try {
              response.setContentType("application/json;charset=utf-8");
              //返回401状态码 权限不足
              response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
              //响应流
              PrintWriter out=response.getWriter();
              //封装返回数据
              Map<String,Object> resultMap=new HashMap<String,Object>();
              resultMap.put("code",HttpServletResponse.SC_UNAUTHORIZED);
              resultMap.put("data","");
              resultMap.put("msg","用户名密码错误");
              //new ObjectMapper().writeValueAsString(resultMap)将map转成json
              out.write(new ObjectMapper().writeValueAsString(resultMap));
              out.flush();
              out.close();
          }catch (Exception outEX){
              outEX.printStackTrace();
          }
            throw new RuntimeException(e);
        }

    }

    @Override
    public void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
       AuthorityUser user=(AuthorityUser)authResult.getPrincipal();
     /*  user.setId(((AuthorityUser)authResult.getPrincipal()).getId());
       user.setUsername(authResult.getName());
       user.setAuthorityRoles((List<AuthorityRole>) authResult.getAuthorities());*/
        String token= JwtUtil.generateTokenExpireInMinutes(user,rsaKeyProperties.getPrivateKey(),24 * 60);
        response.setHeader("Authorization","bearer "+token);
        try {
            //将token保存到数据库当中
            int reslut=userDao.updateUserToken(((AuthorityUser)authResult.getPrincipal()).getId(),token);
            //如果保存成功给用户返回
            if(reslut>0){
             response.setContentType("application/json;charset=utf-8");
             //返回200状态码
             response.setStatus(HttpServletResponse.SC_OK);
             //响应流
             PrintWriter out=response.getWriter();
             //封装返回数据
             Map<String,Object> resultMap=new HashMap<String,Object>();
             resultMap.put("code",HttpServletResponse.SC_OK);
             resultMap.put("data","");
             resultMap.put("msg","认证通过");
             //new ObjectMapper().writeValueAsString(resultMap)将map转成json
             out.write(new ObjectMapper().writeValueAsString(resultMap));
             out.flush();
             out.close();
         }
        }catch (Exception outEX){
            outEX.printStackTrace();
            userDao.updateUserToken(((AuthorityUser)authResult.getPrincipal()).getId(),"");
        }
    }
}
